package jMiiEditor.gui.swingintrospection;

import java.util.Map;
import org.apache.log4j.Logger;
import cx.ath.choisnet.lang.introspection.IntrospectionInvokeException;
import cx.ath.choisnet.swing.introspection.ObjectPopulatorHelper;
import cx.ath.choisnet.swing.introspection.SwingIntrospectorIllegalAccessException;
import cx.ath.choisnet.swing.introspection.SwingIntrospectorItem;
import cx.ath.choisnet.swing.introspection.SwingIntrospectorParseException;
import cx.ath.choisnet.swing.introspection.SwingIntrospectorRootItem;
import cx.ath.choisnet.swing.introspection.SwingIntrospectorUnsupportedClassException;
import jMiiEditor.mii.MIIGETTER;
import jMiiEditor.mii.Mii;
import jMiiEditor.mii.introspection.MiiGetterIntrospectionBadParameterException;
import jMiiEditor.mii.introspection.MiiGetterIntrospectionItem;

// TODO: Must be more generic ! (super class should deal with defaults types)
public class SwingIntrospectorMiiPopulater<FRAME>
{
    /** Some logs */
    private static Logger slogger = Logger.getLogger(SwingIntrospectorMiiPopulater.class);

    private Mii     populateMiiObject;
    private FRAME   readingObject;

    public SwingIntrospectorMiiPopulater( Mii populateMiiObject, FRAME readingObject )
    {
        this.populateMiiObject = populateMiiObject;
        this.readingObject     = readingObject;
    }

    public void populate( 
            MiiGetterIntrospectionItem              miiItem,
            final SwingIntrospectorRootItem<FRAME>  rootItem
            )
        throws SwingIntrospectorIllegalAccessException,
               SwingIntrospectorUnsupportedClassException,
               IntrospectionInvokeException,
               MiiGetterIntrospectionBadParameterException, SwingIntrospectorParseException
    {
        populate( miiItem, rootItem.getRootItemsMap() );
    }

    public void populate( 
            MiiGetterIntrospectionItem                  miiItem, 
            Map<Integer, SwingIntrospectorItem<FRAME>>  rootItemMap 
            )
        throws SwingIntrospectorIllegalAccessException,
               SwingIntrospectorUnsupportedClassException,
               IntrospectionInvokeException, 
               MiiGetterIntrospectionBadParameterException,
               SwingIntrospectorParseException
    {
        MIIGETTER.Type type = miiItem.getType();

        if( rootItemMap.size() == 0 ) {
            slogger.warn( 
                    "Store an object for nothing!!\n"
                    + " -  MiiGetterInspection.Item :" + miiItem + "\n"
                    + " - rootItemMap " + rootItemMap
                    );
            return;
        }

        if( rootItemMap.size() == 1 ) {
            // Only 1 root item
            SwingIntrospectorItem<FRAME> rootItem = rootItemMap.get( 0 );
            
            Object field = rootItem.getFieldObject( readingObject );
            Object value = ObjectPopulatorHelper.getFieldValue( field, miiItem );

            miiItem.setObjectValue( populateMiiObject, value );
            return;
        }
        else if( rootItemMap.size() == 4 ) {
            if( type == MIIGETTER.Type.BYTES4 ) {
                byte[] bytes = new byte[ 4 ];

                for( int i = 0; i<bytes.length; i++ ) {
                    SwingIntrospectorItem<FRAME> item = rootItemMap.get( i );
                    Object field = item.getFieldObject( readingObject );
                    Object value = ObjectPopulatorHelper.getFieldValue( field, miiItem );
                    int iValue = Integer.class.cast( value );
                    
                    bytes[ i ] = (byte)iValue;
                }
                miiItem.setObjectValue( populateMiiObject, bytes );
            }
            else {
                // Don't Known how to handle this case !
                slogger.warn( "Don't kown how to handle this case ! rootItemMap.size() = 4 : type =" + type );
            }
        }
        else if( rootItemMap.size() == 2 ) {
            if( type == MIIGETTER.Type.BOOL ) {
                SwingIntrospectorItem<FRAME> item = rootItemMap.get( 0 );

                Object field = item.getFieldObject( readingObject );
                Object value = ObjectPopulatorHelper.getFieldValue( field, miiItem );
                boolean bvalue = !Boolean.class.cast( value );
                miiItem.setBooleanValue( populateMiiObject, bvalue );
            }
        }
        else {
            // Don't Known how to handle this case !
            slogger.warn( "Don't kown how to handle this case ! rootItemMap.size() = " + rootItemMap.size() + " type =" + type );
        }
    }
}
